package com.bestcem.xm.member.handler.export;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONArray;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.label.dao.LabelValueDao;
import com.bestcem.xm.label.entity.pojo.LabelValueDO;
import com.bestcem.xm.member.constant.Constants;
import com.bestcem.xm.member.controller.v2.param.FilterMembersParam;
import com.bestcem.xm.member.entity.pojo.ExtendFieldDO;
import com.bestcem.xm.member.entity.pojo.MemberDO;
import com.bestcem.xm.member.handler.export.easyExcel.ExcelWriteHandler;
import com.bestcem.xm.member.service.MemberService;
import com.bestcem.xm.member.service.dto.PageDTO;
import com.bestcem.xm.member.util.CheckUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import static com.bestcem.xm.common.core.uitls.DateUtil.convertDteToString;

/**
 * 示例服务
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/8/2
 */
@Slf4j
@Component
public class IndividualMemberExportHandler extends BaseExportHandle {

    @Resource
    private LabelValueDao labelValueDao;

    @Resource
    protected MemberService memberService;

    @Override
    public ServiceResult<File> exportToExcel(ExportContext context) {
        // 查询联系人总数
        FilterMembersParam filterMembersParam = this.convert(context);
        filterMembersParam.setExcludeData(true);
        ServiceResult<PageDTO<MemberDO>> filterMembers = memberService.baseFilterMembers(filterMembersParam);
        if(!filterMembers.isSuccess()){
            log.error("联系人导出异常:{}", filterMembers.getMsg());
            return ServiceResult.fail("联系人导出异常");
        }
        context.setMemberCount(filterMembers.getData().getTotal());

        // 获取文件名称
        String fileName = context.getFileName();
        // 获取 门店与id的映射
        Map<String, String> storeIdNameMap = getStoreIdNameMap(context.getOrgId());
        File file = FileUtil.touch(fileName);
        // 获取标签名 与标签值的映射
        Map<String, List<LabelValueDO>> labelValueMap = getLabelValueMap(context.getOrgId(), context.getMType());

        // 获取所有的扩展字段
        List<ExtendFieldDO> extendFields = getExtendFields(context.getOrgId(), context.getMType());
        // 获取表头
        Map<String, String> headerTypeMap = new HashMap<>();
        List<List<String>> heads = getMemberHeader(labelValueMap, extendFields, context.getMType(), headerTypeMap);

        // 更新导出状态
        updateExportStatus(0, context.getExportRecordId());
        // 设置进度条初始值
        setProgressBarStatus(context.getExportRecordId(), 0, context.getMemberCount());
        // 获取更新的步长
        int per = calcUpdateProgressStep(context.getMemberCount());

        // 设置导出cell格式
        ExcelWriteHandler excelWriteHandler = new ExcelWriteHandler();
        // 设置映射
        excelWriteHandler.setHeaderTypeMap(headerTypeMap);

        ExcelWriter build = EasyExcel.write(file)
                .registerWriteHandler(excelWriteHandler)
                .useDefaultStyle(false)
                .head(heads)
                .build();
        WriteSheet writeSheet = EasyExcel.writerSheet().sheetName("sheet").build();
        // 分页查询联系人
        filterMembersParam.setRowsPerPage(Constants.MAX_MEMBER_AMOUNT_SINGLE_PAGE);
        filterMembersParam.setExcludeData(false);
        filterMembersParam.setExcludeCount(true);
        for(int page=1;;page++){
            filterMembersParam.setPage(page);
            filterMembers = memberService.baseFilterMembers(filterMembersParam);
            if(!filterMembers.isSuccess()){
                log.error("联系人导出异常:{}", filterMembers.getMsg());
                return ServiceResult.fail("联系人导出异常");
            }

            if(filterMembers.getData() == null || CollectionUtil.isEmpty(filterMembers.getData().getRows())){
                // 若没有联系人数据
                build.write(new ArrayList(), writeSheet);
                break;
            }

            List<MemberDO> members = filterMembers.getData().getRows();
            for (int i = 0; i < members.size(); i++) {
                MemberDO member = members.get(i);
                // 处理数据
                String storeName = "";
                if (StrUtil.isNotEmpty(member.getStoreId())) {
                    // 有门店id
                    if (storeIdNameMap.containsKey(member.getStoreId())) {
                        storeName = storeIdNameMap.get(member.getStoreId());
                    }
                }

                List<List<String>> contents = new ArrayList<>();
                List<String> content = new ArrayList<>();
                // 编号
                content.add(member.getMemberNo());
                // 外部编号
                content.add(member.getOutNo());
                // 姓名
                content.add(member.getName());
                // 微信昵称
                content.add(member.getNickname());
                if (!context.getIsMDisplay()) {
                    // 手机号
                    content.add(CheckUtil.hiddenMobile(member.getPhone()));
                    // 邮箱
                    content.add(CheckUtil.hiddenEmail(member.getEmail()));
                } else {
                    // 手机号
                    content.add(member.getPhone());
                    // 邮箱
                    content.add(member.getEmail());
                }
                // 性别
                content.add(member.getGender());
                // 年龄
                if (ObjectUtil.isNotEmpty(member.getAge())) {
                    content.add(member.getAge().toString());
                } else {
                    content.add("");
                }
                // 出生日期
                content.add(convertDteToString(member.getBirthday(), "yyyy/M/d"));
                // 所属组织
                content.add(storeName);
                //地址
                String addressStr = member.getAddress();
                if (StrUtil.isNotEmpty(addressStr)) {
                    List<String> address = JSONArray.parseArray(addressStr, String.class);
                    // 处理有问题的数据
                    dealAddress(address);

                    // 省份
                    content.add(address.get(0));
                    // 城市
                    content.add(address.get(1));
                    // 区县
                    content.add(address.get(2));
                    // 街道信息
                    content.add(address.get(3));
                } else {
                    // 省份
                    content.add("");
                    // 城市
                    content.add("");
                    // 区县
                    content.add("");
                    // 街道信息
                    content.add("");
                }
                // 微信openid
                content.add(member.getOpenId());
                // 微信appid
                content.add(member.getAppId());
                // 支付宝id
                content.add(member.getAliPayUserId());
                // 创建时间
                if(member.getCreateTime() != null){
                    content.add(convertDteToString(member.getCreateTime(), DateUtil.MEMBER_EXPORT_FORMAT));
                }else{
                    content.add("");
                }
                // 扩展字段
                buildExcelField(member.getFieldValList(), context.getIsMDisplay(), extendFields, content);
                // 标签
                buildExcelLabel(member.getLabels(), labelValueMap, content);
                contents.add(content);
                build.write(contents, writeSheet);
                if (i % per == 0) {
                    // 每per条更新一次进度
                    setProgressBarStatus(context.getExportRecordId(), (i + 1), context.getMemberCount());
                }
            }
        }
        // 设置进度条为99%，1%留给保存文件
        setProgressBarStatus(context.getExportRecordId(), (int) (context.getMemberCount() * 0.99), context.getMemberCount());
        build.finish();
        return ServiceResult.success(file);
    }

    /**
     * 获取该组织下相关联系人的所有标签
     *
     * @param orgId
     * @param memberType
     * @return
     */
    private Map<String, List<LabelValueDO>> getLabelValueMap(String orgId, Integer memberType) {
        List<LabelValueDO> labelValues =
                labelValueDao.listByOrgIdAndMemberType(orgId, memberType);
        if (CollUtil.isNotEmpty(labelValues)) {
            // 根据标签名称分组
            LinkedHashMap<String, List<LabelValueDO>> labelMap = labelValues.stream()
                    .collect(Collectors.groupingBy(LabelValueDO::getLabelName, LinkedHashMap::new, Collectors.toList()));

            return labelMap;
        }
        return new HashMap<>();
    }
}
